# -*- coding: utf8 -*-

__author__ = 'sergey'

import traceback
from time import sleep, time
import gobject
from datetime import datetime, timedelta
from threading import Thread, Event

class FindDupArchives(Thread):
    """
    __init__ : args = ( app, ui, db_req, stats_req )
    """

    app = None
    ui = None
    db_req = None
    stats_req = None

    stop_event = None

    log = None

    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, verbose=None):
        self.app, self.ui, self.db_req, self.stats_req = args
        self.stop_event = Event()
        Thread.__init__(self, group, target, name, args, kwargs, verbose)

    def run(self):
        from logger import get_file_logger
        self.log = get_file_logger("worker-FindDupArchives")
        try:
            self.find_duparchives()
        except Exception as e:
            self.log.error(e)
            self.log.error(traceback.format_exc())
        return 0


    def match_func(self, model, iter, data):
        column, key = data # data is a tuple containing column number, key
        value = model.get_value(iter, column)
        return value == key

    def search(self, model, iter, func, data):
        while iter:
            if func(model, iter, data):
                return iter
            result = self.search(model, model.iter_children(iter), func, data)
            if result: return result
            iter = model.iter_next(iter)
        return None


    def add_file_to_treeview(self, file1, file2, file2file, store):

        file1_id_str = str(file2file["file1_id"])
        file2_id_str = str(file2file["file2_id"])

        file1_iter = self.search( store, store.iter_children(None), self.match_func, (0, file1_id_str,) )

        if not file1_iter:
            file1_iter = store.append( None, [
                file1_id_str,
                None,
                self.app.idle_button_del_dup_file_clicked,
                self.db_req.query("get_file_full_path", ( file1, )),
                file2file["file1_count"],
                None,
                None,
                "Удалить"
            ] )

        store.append( file1_iter, [
            None,
            file2_id_str,
            self.app.idle_button_del_dup_file_clicked,
            self.db_req.query("get_file_full_path", ( file2, )),
            file2file["file2_count"],
            file2file["equal_images"],
            file2file["quality_points"],
            "Удалить"
            ] )

        return


    def find_duparchives(self):

        self.log.info("START")

        treeview4 = self.ui.get_object("treeview4")
        store_file = treeview4.get_model()

        store_file.clear()

        self.log.debug("Get file2file count...")
        t1 = datetime.now()
        f2f_count = self.db_req.query("get_file2file_count", ())
        t2 = datetime.now()
        self.log.debug("Got file2file count: %s, in %s" % (f2f_count, t2 - t1))

        processed = 0
        similar = 0

        gobject.idle_add( self.ui.get_object("progressbar_nonuniq_archives").set_text,
            "Обработано: %d из %d (%0.3f%%); Найдено: %d (%0.3f%%)" % (
                processed, f2f_count, processed*100.0/f2f_count,
                similar, similar*100.0/f2f_count
                )
        )

        if not f2f_count:
            self.log.info("STOP")
            return 0

        offset = 0
        count = 20

        self.log.debug(".. offset=%d, count=%d" % (offset, count,))

        req_id = self.db_req.query("get_file2file", (count, offset), no_return=True )
        t1 = datetime.now()
        while not self.db_req.has_result(req_id):
            if self.stop_event.isSet():
                break
            sleep(0.01)
        t2 = datetime.now()
        self.log.debug("Got file2file in %s" % (t2 - t1,))

        t_begin = time()

        while not self.stop_event.isSet():
            item = self.db_req.get_result_row(req_id)

            self.log.debug("Item=%r" % item)
            # print("-- item: %r" % (item,))
            if item is None:
                if offset + count >= f2f_count:
                    break
                offset += count
                self.log.debug(".. offset=%d, count=%d" % (offset, count,))
                req_id = self.db_req.query("get_file2file", (count, offset), no_return=True )
                t1 = datetime.now()
                while not self.db_req.has_result(req_id):
                    if self.stop_event.isSet():
                        break
                    sleep(0.01)
                t2 = datetime.now()
                self.log.debug("Got file2file in %s" % (t2 - t1,))
                continue


            file1 = self.db_req.query("get_file", (item["file1_id"],))
            file2 = self.db_req.query("get_file", (item["file2_id"],))

            self.add_file_to_treeview( file1, file2, item, store_file)

            processed += 1
            p = processed*1.0/f2f_count
            if p < 0:
                p = 0
            if p > 1:
                p = 1

            t_now = time()
            eta =  timedelta( seconds=(f2f_count - processed) / f2f_count * (t_now - t_begin))

            gobject.idle_add( self.ui.get_object("progressbar_nonuniq_archives").set_fraction, p )
            gobject.idle_add( self.ui.get_object("progressbar_nonuniq_archives").set_text,
                "Обработано: %.3f из %d (%0.3f%%), Завершение через: %s" % (
                    processed, f2f_count, processed*100.0/f2f_count, eta
                )
            )


        t_now = time()
        dt =  timedelta( seconds=(t_now - t_begin))

        gobject.idle_add( self.ui.get_object("progressbar_nonuniq_archives").set_fraction, p )
        gobject.idle_add( self.ui.get_object("progressbar_nonuniq_archives").set_text,
            "Обработано: %.3f из %d (%0.3f%%), Заняло: %s" % (
                processed, f2f_count, processed*100.0/f2f_count, dt
                )
        )

        self.log.info("STOP")

        self.stop_event.clear()

        return
